package com.xunk.equipment.controller;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.xunk.common.core.constant.MessageNotifyConstants;
import com.xunk.common.core.domain.ControlDeviceParam;
import com.xunk.common.core.domain.EquipmentInfoVO;
import com.xunk.common.core.domain.EquipmentResponse;
import com.xunk.common.core.utils.DataUtils;
import com.xunk.common.core.utils.JwtUtil;
import com.xunk.common.core.web.domain.AjaxResult;
import com.xunk.common.security.utils.SecurityUtils;
import com.xunk.equipment.api.domain.MessageNotificationDO;
import com.xunk.equipment.domain.EquipmentDO;
import com.xunk.equipment.service.BaseService;
import com.xunk.equipment.service.IEquipmentService;
import com.xunk.equipment.service.ruying.RuYingControlService;
import com.xunk.equipment.vo.response.MessageNotificationResponse;
import com.xunk.equipment.vo.response.RoomInfoVO;
import com.xunk.equipment.vo.response.Weather;
import com.xunk.equipment.websocket.WebsocketManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * @ProjectName: xunk
 * @Package: com.xunk.equipment.controller
 * @ClassName: SwitchController
 * @Author: yangwendong
 * @Description:
 * @Date: 2021/3/30 18:53
 * @Version: 1.0
 */
@RestController
@Slf4j
public class WebController extends BaseController {

    @Autowired
    BaseService baseService;

    @Autowired
    RuYingControlService ruYingControlService;

    /**
     * 获取设备的基本属性信息
     *
     * @param deviceSn
     * @return
     */
    @GetMapping("/info")
    public AjaxResult info(@RequestParam("deviceSn") String deviceSn) {
        //获取设备厂商
        EquipmentDO equipmentDO = getEquipmentInfo(deviceSn);
        IEquipmentService iEquipmentService = getEquipmentServiceHandler(equipmentDO);
        EquipmentResponse info = iEquipmentService.getEquipmentInfo(equipmentDO);
        info.setDeviceName(equipmentDO.getDeviceName());
        info.setRoomNum(equipmentDO.getRoomNum());
        info.setDeviceType(equipmentDO.getDeviceType());
        return AjaxResult.success(info);

    }

    /*
     *     设置设备属性
     *     deviceSn :设备ID
     *     type:控制的属性
     *     value: 属性值
     */

    @GetMapping("/control")
    public AjaxResult control(@RequestParam("deviceSn") String deviceSn, @RequestParam("type") String type, @RequestParam("value") String value) {
        //获取设备参数信息
        EquipmentDO equipmentDO = getEquipmentInfo(deviceSn);
        //获取对应设备的service
        IEquipmentService equipmentService = getEquipmentServiceHandler(equipmentDO);
        return equipmentService.control(equipmentDO, type, value) ? AjaxResult.success() : AjaxResult.error();
    }


    /*
     *     批量设置设备属性
     *     deviceSn :设备ID
     *     type:控制的属性
     *     value: 属性值
     */
    @PostMapping("/batch/control")
    public AjaxResult batchControl(@RequestBody List<ControlDeviceParam> list) {

        List<ControlDeviceParam> errorList = new ArrayList<>();
        for (ControlDeviceParam param : list) {
            //  获取设备参数信息
            EquipmentDO equipmentDO = getEquipmentInfo(param.getDeviceSn());
            //  获取对应设备的service
            IEquipmentService equipmentService = getEquipmentServiceHandler(equipmentDO);
            try {
                Boolean res = equipmentService.control(equipmentDO, param.getType(), param.getValue());
                if (!res) {
                    errorList.add(param);
                }
            } catch (RuntimeException e) {
                errorList.add(param);
            }

        }
        if (!CollectionUtils.isEmpty(errorList)) {
            return AjaxResult.error("存在调整失败设备", errorList);
        }
        return AjaxResult.success();
    }

    /**
     * 获取某个家庭下的所有设备列表
     *
     * @param homeId
     * @param deviceSource
     * @return
     */
    @GetMapping("list")
    public AjaxResult equipmentList(@RequestParam("homeId") Long homeId, @RequestParam(value = "deviceSource", required = false, defaultValue = "0") Integer deviceSource) {
        // 根据homeI获取该家庭下所有的设备id
        List<EquipmentInfoVO> equipmentInfoVOS = baseService.equipmentList(homeId, deviceSource);
        return AjaxResult.success(equipmentInfoVOS);
    }

    /**
     * 获取当前家庭下的房屋编号列表
     *
     * @param homeId
     * @return
     */
    @GetMapping("roomList")
    public AjaxResult roomList(@RequestParam("homeId") Long homeId) {
        // 根据homeId获取该家庭下所有的房屋
        List<RoomInfoVO> roomInfoVOS = baseService.roomList(homeId);
        return AjaxResult.success(roomInfoVOS);
    }

    /**
     * 修改设备备注名
     *
     * @param params post请求体
     * @return
     */
    @PostMapping("/change")
    public AjaxResult changeDeviceName(@RequestBody String params) {

        JSONObject paramsJSONObject = JSONObject.parseObject(params);
        String deviceSn = paramsJSONObject.getObject("deviceSn", String.class);
        String name = paramsJSONObject.getObject("name", String.class);
        baseService.changeDeviceName(deviceSn, name);
        return AjaxResult.success();
    }

    /**
     * 获取天气信息
     *
     * @param districtCode
     * @return
     */
    @GetMapping("/weather")
    public AjaxResult getWeatherInfo(@RequestParam("districtCode") Long districtCode) {
        Weather weatherInfo = baseService.getWeatherInfo(districtCode);
        return AjaxResult.success(weatherInfo);
    }


    /**
     * @param deviceSns
     * @param deptId
     * @return
     */
    @GetMapping("/ruying/delete")
    public AjaxResult deleteRuyingDevice(@RequestParam String deviceSns, @RequestParam Long deptId) {
        System.out.println("deleteRuyingDevice Feign -> Enter");
        Boolean aBoolean = ruYingControlService.deleteRuyingDevice(deviceSns, deptId);
        return aBoolean ? AjaxResult.success() : AjaxResult.error();
    }

    @PostMapping("/message/save")
    public AjaxResult insertMessageNotification(@RequestBody List<MessageNotificationDO> messages) {
        baseService.insertMessageNotifications(messages);
        return AjaxResult.success();
    }

    /**
     * 获取系统消息和设备消息列表
     *
     * @param type
     * @return
     */
    @GetMapping("/message/list")
    public AjaxResult listMessageNotifications(@RequestParam(name = "type", defaultValue = "1") Integer type) {
        startPage();
        Long userId = SecurityUtils.getUserId();
        List<MessageNotificationResponse> list = baseService.listMessageNotifications(userId, type);
        Integer deviceUnreadCount = baseService.countUnReadMessage(userId, MessageNotifyConstants.DEVICE_TYPE);
        Integer systemUnreadCount = baseService.countUnReadMessage(userId, MessageNotifyConstants.SYSTEM_TYPE);
        Map<String, Object> data = new HashMap<>();
        data.put("rows", list);
        data.put("total", new PageInfo(list).getTotal());
        data.put("dCount", deviceUnreadCount);
        data.put("sCount", systemUnreadCount);
        return AjaxResult.success("查询成功", data);
    }

    /**
     * 设置消息为已读状态
     *
     * @param id 如果id=-1，表示设置全部已读
     * @return
     */
    @GetMapping("/message/read")
    public AjaxResult readMessageNotifications(@RequestParam(name = "id") Long id, @RequestParam(name = "type", defaultValue = "1") Integer type) {
        return baseService.readMessageNotification(id, type) ? AjaxResult.success() : AjaxResult.error();
    }
/**************************************************************以下内容后期需要删除******************************************************************/
    /**
     * 测试发送socket信息
     *
     * @param userId
     * @param message
     * @return
     */
    @GetMapping("/socket/message")
    public AjaxResult simulateSocketMessage(@RequestParam String userId, @RequestParam String message) {
        WebsocketManager.appointSending(userId, message);
        return AjaxResult.success();
    }

    @GetMapping("/socket/list")
    public AjaxResult listSocket(@RequestParam(value = "userId", required = false) String userId) {
        Map<String, Object> result = new HashMap<>();
        Integer[] count = {0};
        List<Map<String, Object>> list = new ArrayList<>();
        WebsocketManager.WEBSOCKET_MAP.entrySet().stream().filter(s -> {
            if (DataUtils.isNotEmpty(userId)) {
                return Objects.equals(userId, s.getKey());
            }
            return true;
        }).forEach(entry -> {
            Map<String, Object> m = new HashMap<>();
            m.put("当前登录id", entry.getKey());
            List<Map<String, Object>> l = new ArrayList<>();
            entry.getValue().forEach(v -> {
                Map<String, Object> m1 = new HashMap<>();
                m1.put("最后心跳时间", v.getPongTime());
                m1.put("sessionId", v.getSessionId());
                l.add(m1);
                count[0]++;
            });
            m.put("session信息", l);
            list.add(m);
        });
        result.put("连接总数", count[0]);
        result.put("连接信息", list);
        return AjaxResult.success(result);
    }

    /**
     * 获取如影设备的token
     *
     * @param deptId
     * @return
     */
    @GetMapping("/ruying/token")
    public AjaxResult ruyingToken(@RequestParam Long deptId) {
        String ownId = baseService.findOwnIdByDeptId(deptId);
        String jwtToken = JwtUtil.getRuyingGwt("12345678", ownId);
        return AjaxResult.success(jwtToken);
    }
}
